<?php

namespace app\common\model;

use app\common\library\Auth;
use app\common\model\shop\Order;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use Jdy;
use think\Cache;
use think\Db;
use think\Log;
use think\Model;

/**
 * 会员模型
 */
class User extends Model
{

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    // 追加属性
    protected $append = [
        'url',
        'jointime_text',
        'name_str',
        'month',
        'total',
        'qr_image_str',
        'finishtime_text',
        'new_nickname',
    ];
    public function getNewNicknameAttr($value, $d)
    {
        return $d['nickname'] . '#' . $d['id'];
    }
    public function getFinishtimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['finishtime']) ? $data['finishtime'] : '');
        return is_numeric($value) ? date("Y-m-d", $value) : $value;
    }

    public function getQrImageStrAttr($value, $data)
    {
        return isset($data['qr_image']) && $data['qr_image'] ? request()->domain() . $data['qr_image'] : '';
    }
    public function getNameStrAttr($value, $data)
    {
        return substrCut($data['nickname']);
    }
    public function userLevel()
    {
        return $this->belongsTo('app\common\model\user\Level', 'level_id', 'id', [], 'LEFT')->setEagerlyType(1);
    }
    public function getJointimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['jointime']) ? $data['jointime'] : '');
        return is_numeric($value) ? date("Y-m-d", $value) : $value;
    }
    public function getMonthAttr($value, $data)
    {
        return  Order::where('user_id', $data['id'])->where('status', '99')->whereTime('finished_time', 'month')->sum('total_fee');
    }
    public function getTotalAttr($value, $data)
    {
        return  Order::where('user_id', $data['id'])->where('status', '99')->sum('total_fee');
    }

    protected static function init()
    {
        self::afterInsert(function ($row) {
            // if (empty($row['jdy_id']) && !empty($row['acct_id']) && ($row['acct_id'] == 50 || $row['acct_id'] == 67)) {
            //     $api = new Jdy(['acct_id' => $row['acct_id']]);
            //     $api->addUser($row);
            // }
        });
    }
    /**
     * 获取个人URL
     * @param string $value
     * @param array  $data
     * @return string
     */
    public function getUrlAttr($value, $data)
    {
        return "/u/" . $data['id'];
    }

    /**
     * 获取头像
     * @param string $value
     * @param array  $data
     * @return string
     */
    public function getAvatarAttr($value, $data)
    {
        if (!$value) {
            //如果不需要启用首字母头像，请使用
            $value = '/assets/img/avatar.png';
            // $value = letter_avatar($data['nickname']);
        }
        return cdnurl($value, true);
    }

    /**
     * 获取会员的组别
     */
    public function getGroupAttr($value, $data)
    {
        return UserGroup::get($data['group_id']);
    }

    /**
     * 获取验证字段数组值
     * @param string $value
     * @param array  $data
     * @return  object
     */
    public function getVerificationAttr($value, $data)
    {
        $value = array_filter((array)json_decode($value, true));
        $value = array_merge(['email' => 0, 'mobile' => 0], $value);
        return (object)$value;
    }

    /**
     * 设置验证字段
     * @param mixed $value
     * @return string
     */
    public function setVerificationAttr($value)
    {
        $value = is_object($value) || is_array($value) ? json_encode($value) : $value;
        return $value;
    }

    /**
     * 变更会员余额
     * @param int    $money   余额
     * @param int    $user_id 会员ID
     * @param string $memo    备注
     */
    public static function money($money, $user_id, $memo)
    {
        Db::startTrans();
        try {
            $user = self::lock(true)->find($user_id);
            if ($user && $money != 0) {
                $before = $user->money;
                //$after = $user->money + $money;
                $after = function_exists('bcadd') ? bcadd($user->money, $money, 2) : $user->money + $money;
                //更新会员信息
                $user->save(['money' => $after]);
                //写入日志
                MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after, 'memo' => $memo]);
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }
    }

    /**
     * 变更会员积分
     * @param int    $score   积分
     * @param int    $user_id 会员ID
     * @param string $memo    备注
     */
    public static function score($score, $user_id, $memo)
    {
        Db::startTrans();
        try {
            $user = self::lock(true)->find($user_id);
            if ($user && $score != 0) {
                $before = $user->score;
                $after = $user->score + $score;
                $level = self::nextlevel($after);
                //更新会员信息
                $user->save(['score' => $after, 'level' => $level]);
                //写入日志
                ScoreLog::create(['user_id' => $user_id, 'score' => $score, 'before' => $before, 'after' => $after, 'memo' => $memo]);
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }
    }

    /**
     * 根据积分获取等级
     * @param int $score 积分
     * @return int
     */
    public static function nextlevel($score = 0)
    {
        $lv = array(1 => 0, 2 => 30, 3 => 100, 4 => 500, 5 => 1000, 6 => 2000, 7 => 3000, 8 => 5000, 9 => 8000, 10 => 10000);
        $level = 1;
        foreach ($lv as $key => $value) {
            if ($score >= $value) {
                $level = $key;
            }
        }
        return $level;
    }

    public static function digui($uids, &$arr = [])
    {
        if (!$uids) {
            return $arr;
        }

        // 确保$uids始终是数组
        $currentIds = is_array($uids) ? $uids : [$uids];

        while (!empty($currentIds)) {
            // 一次查询获取所有直接子级
            $childIds = self::whereIn('parent_id', $currentIds)
                ->where('is_channel', 0)
                ->column('id');

            if (empty($childIds)) {
                break; // 没有更多子级，退出循环
            }

            // 将子级ID添加到结果数组
            $arr = array_merge($arr, $childIds);

            // 将当前子级作为下一轮的父级
            $currentIds = $childIds;
        }

        return $arr;
    }
    public static function realUser($param)
    {
        extract($param);
        Db::startTrans();
        try {
            $ModelUser = User::get(['mobile' => $real_mobile]);
            if (!$ModelUser) {
                exception('用户不存在');
            }
            if ($ModelUser->status == 'hidden') {
                exception('账户已冻结，禁止交易');
            }
            if ($ModelUser->is_real == 1) {
                exception('已实名认证');
            }
            $user = User::where('id_card', $id_card)->where('is_real', 1)->find();
            if ($user) {
                exception('身份证号已实名');
            }
            $client = new Client();
            $url = 'https://eid.shumaidata.com/eid/check';
            $res = $client->post($url, [
                'query' => [
                    'idcard' => $id_card,
                    'name' => $name
                ],
                'headers' => [
                    'Authorization' => 'APPCODE e0b7f0eeb55e4f4ebc1bed3f23c855b6',
                ],

            ]);
            $body = $res->getBody();
            $res = json_decode($body, 1);
            if ($res['code'] != 0) {
                exception($res['message']);
            }
            if ($res['result']['res'] == 1) {
                $ModelUser->save([
                    'name' => $name,
                    'id_card' => $id_card,
                    'real_mobile' => $real_mobile,
                    'is_real' => 1,
                ]);
            } else {
                exception($res['result']['description']);
            }

            Db::commit();
        } catch (ClientException $e) {
            Db::rollback();
            $r = $e->getResponse();
            $res = json_decode($r->getBody(), 1);
            exception($res['message']);
        } catch (\Exception $e) {
            Db::rollback();
            exception($e->getMessage());
        }
    }
    // public static function realUser($image, $side)
    // {
    //     Db::startTrans();
    //     try {
    //         // $ModelUser = User::get(Auth::instance()->id);
    //         $client = new Client();
    //         $url = 'https://cardnumber.market.alicloudapi.com/rest/160601/ocr/ocr_idcard.json';
    //         $data = json_encode([
    //             'image' => $image,
    //             'configure' => [
    //                 'side' => $side,
    //             ]
    //         ]);
    //         $res = $client->post($url, [
    //             'body' => $data,
    //             'headers' => [
    //                 'Authorization' => 'APPCODE e0b7f0eeb55e4f4ebc1bed3f23c855b6',
    //             ],
    //         ]);
    //         $body = $res->getBody();
    //         $res = json_decode($body, 1);

    //         if ($res['success'] != true) {
    //             exception($res['message']);
    //         }
    //         // $ModelUser->name = $res['name'];
    //         // $ModelUser->id_card = $id_card;
    //         // $ModelUser->real = 1;
    //         // $ModelUser->save();
    //         Db::commit();
    //     } catch (ClientException $e) {
    //         Db::rollback();
    //         $r = $e->getResponse();
    //         $res = json_decode($r->getBody(), 1);
    //         Log::write(var_export($res, true), 'error');
    //         if (isset($res['message'])) {
    //             exception($res['message']);
    //         } else {
    //             exception($e->getMessage());
    //         }
    //     } catch (\Exception $e) {
    //         Db::rollback();
    //         exception($e->getMessage());
    //     }
    //     return $res;
    // }
    public static function fxface($data, $base64Str, $imagex, $imagey)
    {
        Db::startTrans();
        try {
            $userinfo = User::get(['id_card' => $data['num'], 'is_real' => 1]);
            if ($userinfo) {
                exception('该身份证已被注册');
            }
            $client = new Client();
            $url = 'https://fxface.market.alicloudapi.com/efficient/idfaceIdentity';
            $form_params = [
                'name' => $data['name'],
                'number' =>  $data['num'],
                'base64Str' => $base64Str,

            ];
            // https://1243test.ciyuantiaoyue.com/uploads/20250228/2fac956bed8de675b6c93c772ebe8349.jpg
            // https://1243test.ciyuantiaoyue.com/uploads/20250228/c5f6e9765500ae59acc816ff54366dec.jpg
            $res = $client->post($url, [
                'form_params' => $form_params,
                'headers' => [
                    'Authorization' => 'APPCODE e0b7f0eeb55e4f4ebc1bed3f23c855b6',
                ],
            ]);
            $body = $res->getBody();
            $res = json_decode($body, 1);

            if ($res['error_code'] != 0) {
                exception($res['reason']);
            }
            $msg = [
                -1 => "身份证和姓名不一致",
                -2 => "公安库中无此身份证记录",
                -3 => "公安身份证库中没有此号码的照片",
                -4 => "照片参数不合格",
                -5 => "照片相片体积过大",
                -6 => "请检查图片编码",
                -7 => "照片相片体积过小",
                1 => "系统分析为同一人",
                2 => "系统分析可能为同一人",
                3 => "系统分析为不是同人",
                4 => "没检测到人脸",
                5 => "疑似非活体",
                6 => "出现多张脸",
                7 => "身份证和姓名一致，官方人脸比对失败",
            ];
            if ($res['result']['Validate_Result'] == 1) {
                $ModelUser = User::get(Auth::instance()->id);
                $ModelUser->save([
                    'name' => $data['name'],
                    'id_card' => $data['num'],
                    'imagex' => $imagex,
                    'imagey' => $imagey,
                    'face_image' =>  saveBase64('data:image/png;base64,' . $base64Str),
                    'is_real' => 1,
                ]);
            } else {
                exception($msg[$res['result']['Validate_Result']]);
            }
            Db::commit();
        } catch (ClientException $e) {
            Db::rollback();
            $r = $e->getResponse();
            $res = json_decode($r->getBody(), 1);
            Log::write(var_export($res, true), 'error');
            if (isset($res['message'])) {
                exception($res['message']);
            } else {
                exception($e->getMessage());
            }
        } catch (\Exception $e) {
            Db::rollback();
            exception($e->getMessage());
        }
        return true;
    }

    public static function add_sign($user, $img, $type = 1)
    {
        $image = imagecreatefrompng(ROOT_PATH . "/public/cert{$type}.png");
        // $image = imagecreatefrompng(ROOT_PATH . "/public/cert.png");

        $textcolor = imagecolorallocate($image, 0, 0, 0);
        $font = ROOT_PATH . "/public/STKAITI.ttf";
        $image2 = imagecreatefrompng(ROOT_PATH . "/public" . $img);
        $size = getimagesize(ROOT_PATH . "/public" . $img);
        $image3 = imagecreatefrompng(ROOT_PATH . "/public/sign.png");


        $path = ROOT_PATH . "/public/cert/";
        if (!is_dir($path)) {
            @mkdir($path, 0755, true);
        }
        $filename = $user->id . '_' . $type . "_" . time() . ".png";
        // $image2 = imagerotate($image2, 90, 0);

        if ($type == 1) {
            imagettftext($image, 20, 0, 216, 2500, $textcolor, $font, date("Y"));
            imagettftext($image, 20, 0, 310, 2500, $textcolor, $font, date("m"));
            imagettftext($image, 20, 0, 386, 2500, $textcolor, $font, date("d"));

            imagecopyresampled($image, $image2, 311, 2518, 0, 0, 230, 100, $size[0] ?? 1074, $size[1] ?? 873);
            imagecopyresampled($image, $image3, 311, 2605, 0, 0, 232, 232, 232, 232);
        } elseif ($type == 5) {

            imagettftext($image, 20, 0, 256, 3205, $textcolor, $font, date("Y"));
            imagettftext($image, 20, 0, 361, 3205, $textcolor, $font, date("m"));
            imagettftext($image, 20, 0, 446, 3205, $textcolor, $font, date("d"));

            imagecopyresampled($image, $image2, 358, 3249, 0, 0, 230, 100, $size[0] ?? 1074, $size[1] ?? 873);

            imagecopyresampled($image, $image3, 370, 3340, 0, 0, 232, 232, 232, 232);

            imagettftext($image, 20, 0, 305, 250, $textcolor, $font, $user['name']);
            imagettftext($image, 20, 0, 433, 302, $textcolor, $font, $user['id_card']);
        }
        imagepng($image, $path . $filename);
        $name = "sign{$type}_image";
        $user->$name = "/cert/" . $filename;
        $user->save();
        return ['code' => 0, 'data' => ['sign_image' => $user->$name]];
    }

    /**
     * 获取所有下线用户ID（非递归实现）
     * @param array $parentIds 父级用户ID数组
     * @param bool $includeSelf 是否包含自己
     * @return array 所有下线用户ID数组
     */
    public static function getAllSubordinates($parentIds, $includeSelf = true)
    {
        if (!is_array($parentIds)) {
            $parentIds = [$parentIds];
        }

        $allIds = $includeSelf ? $parentIds : [];
        $currentIds = $parentIds;

        while (!empty($currentIds)) {
            // 一次查询获取所有直接子级
            $childIds = self::whereIn('parent_id', $currentIds)
                ->where('is_channel', 0)
                ->column('id');

            if (empty($childIds)) {
                break; // 没有更多子级，退出循环
            }

            // 将子级ID添加到结果数组
            $allIds = array_merge($allIds, $childIds);

            // 将当前子级作为下一轮的父级
            $currentIds = $childIds;
        }

        return array_unique($allIds);
    }
}
